package k8s

import (
	"errors"
	"gitee.com/hexug/go-tools/logger"
	"sync"
)

var (
	// 获取K8sClient实例 制定命名空间
	GetK8sInc               = getK8sInstance
	GetK8sIncFromKubeConfig = getK8sInstanceFromKubeConfig
)

// Optimize concurrency control and caching
var (
	k8serInstances = make(map[string]*implK8s)
	mu             sync.RWMutex
)

func getK8sInstance(ns string) (K8sClient, error) {
	if ns == "" {
		logger.L().Error("k8s namespace is empty")
		return nil, errors.New("k8s namespace is empty")
	}

	mu.RLock()
	if ks, exists := k8serInstances[ns]; exists {
		mu.RUnlock()
		return ks, nil
	}
	mu.RUnlock()

	mu.Lock()
	defer mu.Unlock()

	// Double-check to avoid race conditions
	if ks, exists := k8serInstances[ns]; exists {
		return ks, nil
	}

	cs, config, err := getClientSet()
	if err != nil {
		logger.L().Errorf("Get k8s in-cluster clientset failed. error: %v", err)
		return nil, errors.New("create k8s clientset failed")
	}

	ks := &implK8s{Namespace: ns, Clientset: cs, Config: config}
	k8serInstances[ns] = ks
	return ks, nil
}

func getK8sInstanceFromKubeConfig(ns string, kubeConfigPath string) (K8sClient, error) {
	if ns == "" {
		logger.L().Error("k8s namespace is empty")
		return nil, errors.New("k8s namespace is empty")
	}

	mu.RLock()
	if ks, exists := k8serInstances[ns]; exists {
		mu.RUnlock()
		return ks, nil
	}
	mu.RUnlock()

	mu.Lock()
	defer mu.Unlock()

	// Double-check to avoid race conditions
	if ks, exists := k8serInstances[ns]; exists {
		return ks, nil
	}

	cs, config, err := getClientSetFromKubeConfig(kubeConfigPath)
	if err != nil {
		logger.L().Errorf("Get k8s clientset from kubeconfig failed. error: %v", err)
		return nil, errors.New("create k8s clientset failed")
	}

	ks := &implK8s{Namespace: ns, Clientset: cs, Config: config}
	k8serInstances[ns] = ks
	return ks, nil
}
